package suggestie1;
import java.awt.Point;
import java.util.Vector;
import java.util.ArrayList;

public class Triangle {
	private Point v1;
	private Point v2;
	private Point v3;
	private int minx;
	private int maxx;
	private int miny;
	private int maxy;
	private static Point offscreen = new Point (-10, -10);
	private static Point offscreen2 = new Point (-1010, -10);
	public Triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
		v1 = new Point();
		v2 = new Point();
		v3 = new Point();
		minx = Math.min(Math.min(x1,x2),x3);
		maxx = Math.max(Math.max(x1,x2),x3);
		miny = Math.min(Math.min(y1,y2),y3);
		maxy = Math.max(Math.max(y1,y2),y3);
		v1.setLocation(x1,y1);
		v2.setLocation(x2,y2);
		v3.setLocation(x3,y3);
	}
	public boolean rasterize(Point x) {
		Vector<Float> b = barycentrics(x);
		System.out.println(x.toString());
		if(b.elementAt(0)>1 || b.elementAt(0) <0 || b.elementAt(1) >1 || b.elementAt(1) < 0 || b.elementAt(2) > 1 || b.elementAt(2) < 0)
		{
			return false;
		}
		if(b.elementAt(0)<=1 && b.elementAt(0)> 0 && b.elementAt(1)<=1 && b.elementAt(1)> 0 && b.elementAt(2) <=1 && b.elementAt(2)>0) {
			return true;
		}
		else if(b.elementAt(0)==0)
		{
			//beta = 0 testing should be done on v2
			return checkDiagonal(v3,v1,v2);
			
		}
		else if(b.elementAt(1)==0)
		{
			//check v3
			return checkDiagonal(v1,v2,v3);
		}
		else if(b.elementAt(2)==0)
		{
			return checkDiagonal(v3,v2,v1);
		}
		return false;
	}
	private boolean checkDiagonal(Point a, Point b, Point c) {
		double off1 = (whichside( a, b, offscreen)*whichside(a,b,c));
		if(off1 > 0) return true;
		if(off1 < 0) return false;
		// at this point the offscreen point must lie on the triangle side
		return (whichside( a, b, offscreen2)*whichside(a,b,c))>=0;
	}
	private double whichside(Point a, Point b, Point c)
	{
		return ((b.x - a.x)*(c.y - a.y) - (b.y - a.y)*(c.x - a.x));
	}

	public Vector<Integer> getSpans() {
		Vector<Integer> v = new Vector<Integer>();
		v.add(minx);
		v.add(maxx);
		v.add(miny);
		v.add(maxy);
		return v;
	}
	
	private Vector<Float> barycentrics(Point x) {
		// In this definition of the barycentric coordinates, the system from the slides is solved, 
		// with a=v1,b=v2,c=v3. The barycentrics vector returned then consists of
		// [beta,gamma,alpha]
		Vector<Float> bary = new Vector<Float>();
		float a = (float) (v2.getX()-v1.getX());
		float b = (float) (v3.getX()-v1.getX());
		float c = (float) (v2.getY()-v1.getY());
		float d = (float) (v3.getY()-v1.getY());
		float x0 = (float) (x.getX()-v1.getX());
		float y0 = (float) (x.getY()-v1.getY());
		bary.add(0, -(b*y0-x0*d)/(a*d-c*b));
		bary.add(1,(a*y0-c*x0)/(a*d-c*b));
		//alpha
		bary.add(2,1-(bary.elementAt(0)+bary.elementAt(1)));
		return bary;
	}
	public ArrayList<Point> getCoordinates() {
		ArrayList<Point> a = new ArrayList<Point>(3);
		a.add(0,v1);
		a.add(1,v2);
		a.add(2,v3);
		return a;
		
	}

}
